import os,glob,sys,string
from ini import ini_file
from common import *
from gamemap import TiledLayer,Matrix,HomeBase,GameMap
from tiledtmxloader import TileMapParser,ImageLoaderPygame
from pygame.rect import Rect

class TileMapLoader:
    def __init__(self,map_path):
        self.map_path = map_path
        map_files = self._getAllMaps(map_path)
        maps = {}
        for file_name in map_files:
            try:
                map_name = os.path.split(os.path.splitext(file_name)[0])[1]
                maps[map_name] = file_name
            except Exception,errmsg:
                raise SystemExit(errmsg)

        self.maps = maps


    def getTiledLayer(self,parallax_layers):
        ''' create a TiledLayer(Drawable) object from the map 
            and create & connect the linked parallax layers as well'''
        fg_layer = TiledLayer(self.game_map)

        if parallax_layers == 1 or parallax_layers == 3:
            file_name = '%s_p_layer_1%s'%(os.path.splitext(self.file_name))
            world_map,game_map = self._getGameMap(file_name,False)
            background_layer = TiledLayer(game_map)
            # link scroll layers together
            fg_layer.link(background_layer, 0.25)
        if parallax_layers == 2 or parallax_layers == 3:
            file_name = '%s_p_layer_2%s'%(os.path.splitext(self.file_name))
            world_map,game_map = self._getGameMap(file_name,False)
            middle_layer = TiledLayer(game_map)
            fg_layer.link(middle_layer, 0.5)
        return fg_layer  
            
    def getAllMapNames(self):
        return self.maps.keys()#.sort()

    def getGameMap(self,name):
        self.name = name
        self.file_name = self.maps[name]
        self.world_map,self.game_map = self._getGameMap(self.file_name)
        return self.game_map
        
        
    def _getGameMap(self,file_name,main_map=True):
        world_map = world_map = TileMapParser().parse_decode(file_name)
        # load the images using pygame
        world_map.load(ImageLoaderPygame())
        if main_map:
            # only extract map objects if it is the game map (and not if it's the parallax layer)
            self._parseObjects(world_map)
        self._convertTileSurfaces(world_map)
        gm = self.__buildMap(world_map, world_map.layers[0])
        game_map = GameMap(gm,world_map.tilewidth,world_map.tileheight,world_map.indexed_tiles,
                           startingPositions=self.player_pos,#((60,60),(150,60),),
                           bases=self.bases,
                           bgcolor=(0,0,0),
                           relative_speed=1.0)
        
        return world_map,game_map
        
    def _convertTileSurfaces(self,world_map):
        world_map.indexed_tiles = dict((idx, (offx, offy, screen_img.convert())) for idx, (offx, offy, screen_img) in world_map.indexed_tiles.items())
                            
    def _getAllMaps(self,path):
        ' get all the map ini files avaible '
        maps = []
        for dir in os.listdir(path):
            dir = os.path.join(path,dir)
            if not os.path.isdir(dir):
                continue
            map_files = glob.glob(os.path.join(dir,'*.tmx'))
            if map_files:
                for map_file in map_files:
                    if '_p_layer' in map_file:
                        # skip parallax layers.
                        continue
                    maps.append(map_file)
        return maps
    
    def __buildMap(self,world_map,layer):
        '''
        Parse the tmx map into a simple matrix map.
        '''
        from array import array
        map_ = Matrix([])
        idx = 0
        for y in xrange(0, layer.pixel_height, world_map.tileheight):
            row = array('i')
            for x in xrange(0, layer.pixel_width, world_map.tilewidth):
                # add offset in number of tiles
                x += layer.x * world_map.tilewidth
                y += layer.y * world_map.tileheight
                # get the gid at this position
                img_idx = layer.decoded_content[idx]
                idx += 1
                row.append(img_idx)
#                if img_idx:
#                    offx, offy, screen_img = world_map.indexed_tiles[img_idx]
            map_.append(row)
#        for row in map_:
#            print ''.join(str(int(r!=0)) for r in row)
        
        return map_

    def _parseObjects(self,world_map):
        self.player_pos = []
        
        self.bases = []
        for obj_group in world_map.object_groups:
            goffx = obj_group.x
            goffy = obj_group.y
            for map_obj in obj_group.objects:
                if map_obj.type == 'player':
                    self.player_pos.append((goffx + map_obj.x, goffy + map_obj.y))
                if map_obj.type in ('base','homebase'):
                    self.bases.append(HomeBase(Rect(goffx + map_obj.x, goffy + map_obj.y,map_obj.width, map_obj.height)))
#                if map_obj.image_source:
#                    surf = pygame.image.load(map_obj.image_source)
#                    surf = pygame.transform.scale(surf, size)
#                else:
#                    if map_obj.type == 'player':
#                        self.player_pos.append((goffx + map_obj.x, goffy + map_obj.y))


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((640,480))

    m =TileMapLoader(r'./Maps')
    print m.maps
    map = m.getGameMap(m.maps.keys()[0])
    print map
#    print m.getTiledLayer(0)
#    print m.getAllMapNames()